﻿/*
 * debug.h
 *
 */
#ifndef __GDK_DEBUG_H__
#define __GDK_DEBUG_H__

#include <gdk/core/Types.h>
#include <gdk/core/String.h>

#if !defined(_WIN32)
#	include <errno.h>
#endif

#if defined(_WIN32)
#	pragma warning(disable:4091)
#	include <crtdbg.h>
#	include <dbghelp.h>
#endif


namespace gdk
{

#ifdef _WIN32
	__INLINE__ int getLastError(void) { return ::GetLastError(); }
#else
	__INLINE__ int getLastError(void) { return errno; }
#endif

	GDK_CORE_EXPORT String getErrorString(int err);
	GDK_CORE_EXPORT String getLastErrorString(void);


#ifdef _WIN32
	////////////////////////////////////////////////////////
	class GDK_CORE_EXPORT DebugHelper
	{
	public:
		// Typedefs for explicit dynamic linking with functions exported from dbghelp.dll.
		typedef BOOL (__stdcall *SymInitialize_t) (HANDLE hProcess, PCWSTR UserSearchPath, BOOL fInvadeProcess);
		typedef BOOL (__stdcall *SymCleanup_t) (HANDLE hProcess);
		typedef DWORD (__stdcall *SymGetOptions_t) (VOID);
		typedef DWORD (__stdcall *SymSetOptions_t) (DWORD SymOptions);
		typedef BOOL (__stdcall *StackWalk64_t) (DWORD MachineType, HANDLE hProcess, HANDLE hThread, LPSTACKFRAME64 StackFrame,
												 PVOID ContextRecord, PREAD_PROCESS_MEMORY_ROUTINE64 *ReadMemoryRoutine,
												 PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTablAccessRoutine,
												 PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine,
												 PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress);
		typedef PVOID (__stdcall *SymFunctionTableAccess64_t) (HANDLE hProcess, DWORD64 AddrBase);
		typedef DWORD64 (__stdcall *SymGetModuleBase64_t) (HANDLE hProcess, DWORD64 qwAddr);
		typedef BOOL (__stdcall *SymGetLineFromAddr64_t) (HANDLE hProcess, DWORD64 qwAddr, PDWORD pdwDisplacement,
														  PIMAGEHLP_LINE64 Line64);
		typedef BOOL (__stdcall *SymFromAddr_t) (HANDLE hProcess, DWORD64 Address, PDWORD64 Displacement,
												 PSYMBOL_INFO Symbol);
	private:
		HMODULE  _dbghelp;// Handle to the Debug Help Library
	public:
		// Pointers to explicitly dynamically linked functions exported from dbghelp.dll.
		SymInitialize_t                SymInitialize;
		SymCleanup_t                   SymCleanup;
		SymGetOptions_t                SymGetOptions;
		SymSetOptions_t                SymSetOptions;
		StackWalk64_t                  StackWalk64;
		SymFunctionTableAccess64_t     SymFunctionTableAccess64;
		SymGetModuleBase64_t           SymGetModuleBase64;
		SymFromAddr_t                  SymFromAddr;
		SymGetLineFromAddr64_t         SymGetLineFromAddr64;

	private:
		DebugHelper(void);
		~DebugHelper(void);

	public:
		static const DebugHelper& getDebugHelper(void);
	};
#endif



}//namespace gdk






#endif /*__GDK_DEBUG_H__*/
